package com.zxy.supplier_system.server.utils.tencent.position

import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.springframework.web.client.RestTemplate
import java.net.URLEncoder
import java.security.MessageDigest

class TencentWebPositionClient(
    internal val key: String,
    internal val secretKey: String,
) {

    internal val restTemplate = RestTemplate()
    internal val host = "https://apis.map.qq.com"
    internal val objectMapper = jacksonObjectMapper().apply {
        this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
    }

    /**
     * 计算请求签名
     * @param params 请求参数Map
     * @return 计算得到的签名
     */
    internal fun calculateSignature(params: Map<String, String>, api: String): CalculateSignatureResult {
        // 1. 按参数名排序
        val sortedParams = params.toSortedMap()

        // 2. 拼接键值对
        val queryString = sortedParams.entries
            .joinToString("&")
            { (key, value) ->
                "$key=${value}"
            }
        val string = "$api?$queryString$secretKey"
        val signature = md5(string)
        return CalculateSignatureResult(
            "$api?" + sortedParams.entries.joinToString("&")
        { (key, value) ->
            "$key=${URLEncoder.encode(value, "UTF-8")}"
        } + "&sig=$signature",signature)
    }

    class CalculateSignatureResult
        (
        val path:String,
        val signature: String,
    )

    /**
     * MD5加密
     */
    private fun md5(input: String): String {
        val digest = MessageDigest.getInstance("MD5")
        val result = digest.digest(input.toByteArray(Charsets.UTF_8))
        return result.joinToString("") { "%02x".format(it) }
    }

    /**
     * 扩展函数：将Map转换为MultiValueMap用于请求参数
     */
    internal fun Map<String, String>.toQueryParams(): org.springframework.util.MultiValueMap<String, String> {
        val multiValueMap = org.springframework.util.LinkedMultiValueMap<String, String>()
        this.forEach { (key, value) -> multiValueMap.add(key, value) }
        return multiValueMap
    }



}